package com.resource.loginlogoutmanange.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.lang.UUID;
import com.resource.common.utils.AppResponse;
import com.resource.common.utils.PageUtils;
import com.resource.loginlogoutmanange.config.LoginTypeEnum;
import com.resource.loginlogoutmanange.config.PasswordEncoder;
import com.resource.loginlogoutmanange.config.UserHolder;
import com.resource.loginlogoutmanange.dto.LoginDTO;
import com.resource.loginlogoutmanange.entity.TLoginInformationEntity;
import com.resource.loginlogoutmanange.mapper.TLoginInformationDao;
import com.resource.loginlogoutmanange.service.TLoginInformationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.resource.common.utils.Query;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;

import static com.resource.loginlogoutmanange.config.SystemConstants.LOGIN_USER_KEY;
import static com.resource.loginlogoutmanange.config.SystemConstants.LOGIN_USER_TTL;

@Slf4j
@Service("tLoginInformationService")
public class TLoginInformationServiceImpl extends ServiceImpl<TLoginInformationDao, TLoginInformationEntity> implements TLoginInformationService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private TLoginInformationService tLoginInformationService;

    @Resource
    private TLoginInformationDao tLoginInformationDao;

    @Override
    public AppResponse login(LoginDTO loginDTO, HttpSession httpSession) {
        String userName = loginDTO.getUserName();
        String password = loginDTO.getPassword();
        Integer loginType = loginDTO.getLoginType();
        AppResponse appResponse = verifyData(userName, password, loginType);
        //校验不通过
        if(Boolean.FALSE.equals(appResponse.getData())){
            return appResponse;
        }
        QueryWrapper<TLoginInformationEntity> tLoginInformationEntityQueryWrapper = new QueryWrapper<>();
        tLoginInformationEntityQueryWrapper.eq("user_name",userName);
        TLoginInformationEntity tLoginInformationEntity = tLoginInformationDao.selectOne(tLoginInformationEntityQueryWrapper);
        if(Objects.isNull(tLoginInformationEntity)){
            return AppResponse.unknownError("当前用户不存在,请注册");
        }
        String passwordSelect = tLoginInformationEntity.getPassword();
        log.info("数据库正确密码:"+passwordSelect);
        String encodePassord = PasswordEncoder.encode(password);
        log.info("用户输入密码:"+encodePassord);
        //校验密码正确性
        Boolean matches = PasswordEncoder.matches(passwordSelect, encodePassord);
        if(matches==false){
            return AppResponse.unknownError("当前用户密码输入错误");
        }
        Map<String, Object> stringObjectMap = BeanUtil.beanToMap(tLoginInformationEntity, new HashMap<>(), CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) ->
                fieldValue.toString()
        ));
        //随机生成token，作为登录令牌
        String token = UUID.randomUUID().toString(true);
        String loginToken=LOGIN_USER_KEY+token;
        //用户信息存入redis
        stringRedisTemplate.opsForHash().putAll(loginToken,stringObjectMap);
        //设置token过期时间
        stringRedisTemplate.expire(loginToken,LOGIN_USER_TTL, TimeUnit.MINUTES);
        return AppResponse.success("登录成功");
    }

    private AppResponse verifyData(String userName, String password, Integer loginType) {
        if(Objects.isNull(userName) || userName==""){
            return AppResponse.success("用户名为空,请重新输入",false);
        }
        if(Objects.isNull(password) || password==""){
            return AppResponse.success("密码为空,请重新输入",false);
        }
        if(Objects.isNull(loginType)){
            return AppResponse.success("请选择登录的方式",false);
        }
        return AppResponse.success("校验成功",true);
    }

    @Override
    public AppResponse register(LoginDTO loginDTO, HttpSession httpSession) {
        String userName = loginDTO.getUserName();
        String password = loginDTO.getPassword();
        Integer loginType = loginDTO.getLoginType();
        AppResponse appResponse = verifyData(userName, password, loginType);
        //校验不通过
        if(Boolean.FALSE.equals(appResponse.getData())){
            return appResponse;
        }
        QueryWrapper<TLoginInformationEntity> tLoginInformationEntityQueryWrapper = new QueryWrapper<>();
        tLoginInformationEntityQueryWrapper.eq("user_name",userName);
        TLoginInformationEntity tLoginInformationEntity = tLoginInformationDao.selectOne(tLoginInformationEntityQueryWrapper);
        if(!Objects.isNull(tLoginInformationEntity)){
            return AppResponse.unknownError("当前用户已经存在,不能多次注册");
        }
        String encodePassword = PasswordEncoder.encode(password);
        TLoginInformationEntity tLoginInformationEntityNew = new TLoginInformationEntity();
        tLoginInformationEntityNew.setPassword(encodePassword);
        tLoginInformationEntityNew.setUserName(userName);
        tLoginInformationEntityNew.setLoginType(loginType);
        tLoginInformationEntityNew.setIdentify(LoginTypeEnum.parseName(loginType));
        tLoginInformationDao.insert(tLoginInformationEntity);
        return AppResponse.success("注册成功");
    }

    @Override
    public AppResponse logout(String token) {
        //获取当前用户
        TLoginInformationEntity user = UserHolder.getUser();
        String loginToken=LOGIN_USER_KEY+token;
        Map<String, Object> stringObjectMap = BeanUtil.beanToMap(user, new HashMap<>(), CopyOptions.create().setIgnoreNullValue(true).setFieldValueEditor((fieldName, fieldValue) ->
                fieldValue.toString()
        ));
        //移除redis的用户信息
        stringRedisTemplate.opsForHash().delete(loginToken,stringObjectMap);
        return AppResponse.success("注册成功");
    }
}